package com.dtr.zxing.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.dtr.zxing.camera.CameraManager;
import com.dtr.zxing.decode.DecodeThread;
import com.dtr.zxing.utils.BeepManager;
import com.dtr.zxing.utils.CaptureActivityHandler;
import com.dtr.zxing.utils.Const;
import com.dtr.zxing.utils.InactivityTimer;
import com.google.zxing.Result;
import com.tzpay.tzpay.R;
import com.tzpay.tzpay.api.OrderCreate;
import com.tzpay.tzpay.api.OrderQuery;
import com.tzpay.tzpay.api.TzOrderCreateResp;
import com.tzpay.tzpay.bean.OrderInfo;
import com.tzpay.tzpay.presenter.TradeLogicView;
import com.tzpay.tzpay.presenter.TradePresenter;
import com.tzpay.tzpay.ui.BaseFragment;
import com.tzpay.tzpay.ui.activity.TradeResultActivity;
import com.tzpay.tzpay.utils.T;
import com.tzpay.tzpay.utils.Utils;
import com.tzpay.tzpay.view.DilatingDotsDialog;

import java.io.IOException;
import java.lang.reflect.Field;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * Created by chenfeiyue on 16/3/17.
 * <p/>
 * 创建订单
 * 创建成功              失败（提示）（重新扫码）
 * 轮询订单------------------->  Back键（提示框 点击确定调用冲正）
 * 交易成功  交易失败
 * 交易结果页面
 */
public class CaptureFragment extends BaseFragment implements TradeLogicView, SurfaceHolder.Callback, View.OnClickListener {
    private static final int MESAGE_SEARCH_TIMEOUT = 0x100;
    private static final String TAG = "CaptureFragment";
    @Bind(R.id.tv_amt)
    TextView tv_amt;
    @Bind(R.id.capture_scan_line)
    ImageView scanLine;
    @Bind(R.id.capture_preview)
    SurfaceView scanPreview;
    @Bind(R.id.capture_container)
    RelativeLayout scanContainer;
    @Bind(R.id.capture_crop_view)
    RelativeLayout scanCropView;

    private BeepManager beepManager;
    private CameraManager cameraManager;
    private CaptureActivityHandler handler;
    private InactivityTimer inactivityTimer;
    private Rect mCropRect = null;
    private AlertDialog dialog;
    private boolean isHasSurface = false;
    private DilatingDotsDialog dotsDialog;
    private TradePresenter presenter;

    private String authCode;

    /**
     * 是否冲正中
     */
    private boolean isReverse = false;
    /**
     * 收款金额
     */
    private int paymentAmountInt = 0;

    private String orderNo;
    private String orderReqNo;

    public Handler getHandler() {
        return handler;
    }

    public CameraManager getCameraManager() {
        return cameraManager;
    }

    public static CaptureFragment instance() {
        CaptureFragment fragment = new CaptureFragment();
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_capture, null);
        ButterKnife.bind(this, view);
        setUpViews();
        inactivityTimer = new InactivityTimer(getActivity());
        beepManager = new BeepManager(getActivity());
        return view;
    }


    private void setUpViews() {
        Intent intent = getActivity().getIntent();
        String amount = intent.getStringExtra("amount");
        paymentAmountInt = intent.getIntExtra("paymentAmountInt", 0);
        if (TextUtils.isEmpty(amount) || paymentAmountInt == 0) {
            finishActivity();
        }
        tv_amt.setText(amount);
        long durationMillis = 4500;
        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
                0.0f, Animation.RELATIVE_TO_PARENT, 0.9f);
        animation.setDuration(durationMillis);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        scanLine.startAnimation(animation);

    }

    @Override
    public void onResume() {
        super.onResume();

        // CameraManager must be initialized here, not in onCreate(). This is
        // necessary because we don't
        // want to open the camera driver and measure the screen size if we're
        // going to show the help on
        // first launch. That led to bugs where the scanning rectangle was the
        // wrong size and partially
        // off screen.
        cameraManager = CameraManager.getInstance(getActivity().getApplication());

        handler = null;

        if (isHasSurface) {
            // The activity was paused but not stopped, so the surface still
            // exists. Therefore
            // surfaceCreated() won't be called, so init the camera here.
            initCamera(scanPreview.getHolder());
        } else {
            // Install the callback and wait for surfaceCreated() to init the
            // camera.
            scanPreview.getHolder().addCallback(this);
        }
        inactivityTimer.onResume();
    }

    @Override
    public void onPause() {
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        inactivityTimer.onPause();
        beepManager.close();
        cameraManager.closeDriver();
        if (!isHasSurface) {
            scanPreview.getHolder().removeCallback(this);
        }
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        inactivityTimer.shutdown();
        Utils.safeDismissDialog(dialog);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (holder == null) {
            Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
        }
        if (!isHasSurface) {
            isHasSurface = true;
            initCamera(holder);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isHasSurface = false;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    /**
     * A valid barcode has been found, so give an indication of success and show
     * the results.
     *
     * @param rawResult The contents of the barcode.
     * @param bundle    The extras
     */
    public void handleDecode(Result rawResult, Bundle bundle) {
        inactivityTimer.onActivity();
        beepManager.playBeepSoundAndVibrate();
        handleAuthCode(rawResult.toString());
    }

    /**
     * modify 2015.6.23
     * 延迟打开摄像头
     *
     * @param surfaceHolder
     */
    private void initCamera(final SurfaceHolder surfaceHolder) {

        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                if (surfaceHolder == null) {
                    throw new IllegalStateException("No SurfaceHolder provided");
                }

                if (cameraManager.isOpen()) {
                    Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
                    return;
                }
                try {
                    cameraManager.openDriver(surfaceHolder);
                    // Creating the handler starts the preview, which can also throw a
                    // RuntimeException.
                    if (handler == null) {
                        handler = new CaptureActivityHandler(CaptureFragment.this, cameraManager, DecodeThread.ALL_MODE);
                    }

                    initCrop();
                } catch (IOException ioe) {
                    Log.w(TAG, ioe);
                    displayFrameworkBugMessageAndExit();
                } catch (RuntimeException e) {
                    // Barcode Scanner has seen crashes in the wild of this variety:
                    // java.?lang.?RuntimeException: Fail to connect to camera service
                    Log.w(TAG, "Unexpected error initializing camera", e);
                    displayFrameworkBugMessageAndExit();
                }
            }
        }, 50l);
    }

    private void displayFrameworkBugMessageAndExit() {
        // camera error
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(getString(R.string.app_name));
        builder.setMessage("相机打开出错，请稍后重试");
        builder.setCancelable(false);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                getActivity().finish();
            }

        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                getActivity().finish();
            }
        });
        builder.show();
    }

    public void restartPreviewAfterDelay(long delayMS) {
        if (handler != null) {
            handler.sendEmptyMessageDelayed(Const.restart_preview, delayMS);
        }
    }

    public Rect getCropRect() {
        return mCropRect;
    }

    /**
     * 初始化截取的矩形区域
     */
    private void initCrop() {
        int cameraWidth = cameraManager.getCameraResolution().y;
        int cameraHeight = cameraManager.getCameraResolution().x;

        /** 获取布局中扫描框的位置信息 */
        int[] location = new int[2];
        scanCropView.getLocationInWindow(location);

        int cropLeft = location[0];
        int cropTop = location[1] - getStatusBarHeight();

        int cropWidth = scanCropView.getWidth();
        int cropHeight = scanCropView.getHeight();

        /** 获取布局容器的宽高 */
        int containerWidth = scanContainer.getWidth();
        int containerHeight = scanContainer.getHeight();

        /** 计算最终截取的矩形的左上角顶点x坐标 */
        int x = cropLeft * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的左上角顶点y坐标 */
        int y = cropTop * cameraHeight / containerHeight;

        /** 计算最终截取的矩形的宽度 */
        int width = cropWidth * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的高度 */
        int height = cropHeight * cameraHeight / containerHeight;

        /** 生成最终的截取的矩形 */
        mCropRect = new Rect(x, y, width + x, height + y);

//        int[] pixels = Utils.getScreenPixels(CaptureActivity.this);
//        mCropRect = new Rect(0, 0, pixels[0], pixels[1]);
    }

    private int getStatusBarHeight() {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_back:
                getActivity().finish();
                break;
        }
    }

    /**
     * 创建订单
     */
    private void initOperate(String authCode) {
        // 只要到了这个页面就需要刷新流水和账户
        T.e(TAG, "authCode = " + authCode);
        if (presenter == null)
            presenter = new TradePresenter(CaptureFragment.this);
        this.authCode = authCode;
        presenter.getOrderNoFormServer();
    }

    private void handleAuthCode(final String authCode) {
        initDialog();
        initOperate(authCode);
    }

    /**
     * 跳转到交易结果页面
     *
     * @param success
     */
    private void jumpToResult(boolean success, String errorMsg) {

        Intent intent = new Intent(getContext(), TradeResultActivity.class);
        intent.putExtra("RESULT", success);
        intent.putExtra("MESSAGE", errorMsg);
        startActivity(intent);
        finishActivity();
    }

    @Override
    public void showProgress(int type) {
        switch (type) {
            case TradeLogicView.TYPE_CREATE:
                break;
            case TradeLogicView.TYPE_QUERY:
                break;
            case TradeLogicView.TYPE_REVERSE:
                break;

            case TradeLogicView.TYPE_GET_ORDER_NO:
                break;
        }
    }

    @Override
    public void onFailed(int type, String resperr) {
        T.e(TAG, "onFailed ------> " + resperr);
        switch (type) {
            case TradeLogicView.TYPE_CREATE:
                Utils.safeDismissDialog(dialog);
                Utils.safeDismissDialog(dotsDialog);
                showOrderCreateErrorDialog(resperr);
                break;
            case TradeLogicView.TYPE_QUERY:
                // TODO

                if (isReverse)
                    return;
                break;
            case TradeLogicView.TYPE_REVERSE:
                // 冲正失败  关闭页面
                // 做一次查询，修改数据库？OR 直接修改？
                finishActivity();
                break;


            case TradeLogicView.TYPE_GET_ORDER_NO:
                Utils.safeDismissDialog(dialog);
                Utils.safeDismissDialog(dotsDialog);
                showOrderCreateErrorDialog(resperr);
                break;
        }
    }

    @Override
    public void onSuccess(int type, Object result) {
        T.e(TAG, "onSuccess ------> " + result);
        switch (type) {
            case TradeLogicView.TYPE_CREATE:
                // 创建订单成功，轮询订单
                OrderCreate order = (OrderCreate) result;
                orderNo = order.getOrderNo();
                orderReqNo = order.getOrderReqNo();
                presenter.orderQuery(orderNo, orderReqNo);
                break;
            case TradeLogicView.TYPE_QUERY:
                if (isReverse)
                    return;
                // TODO
                OrderQuery query = (OrderQuery) result;
                String status = query.getTransStatus();
                status = status == null ? "" : status;
                /**
                 * 交易状态
                 * A：请求（支付中）
                 * B：成功（支付成功）
                 * C：失败
                 * G：订单作废
                 */
                switch (status) {
                    case OrderInfo.STATUS_PAYING:
                        break;
                    case OrderInfo.STATUS_PAY_SUCCESS:
                        // TODO 支付成功, 跳转成功页
                        jumpToResult(true, "");
                        return;
                    case OrderInfo.STATUS_PAY_FAILED:
                        // TODO 支付失败
                        jumpToResult(false, "支付失败，请稍后再试");
                        return;
                    case OrderInfo.STATUS_INVALID:
                        // TODO 订单已作废
                        jumpToResult(false, "订单已作废，请重新下单");
                        return;
                    default:
                        break;
                }

                presenter.orderQuery(orderNo, orderReqNo);

                break;
            case TradeLogicView.TYPE_REVERSE:
                // 冲正成功 关闭页面
                // 做一次查询，修改数据库？OR 直接修改？
                finishActivity();
                break;


            // 获取订单号成功，下单
            case TradeLogicView.TYPE_GET_ORDER_NO:
                TzOrderCreateResp resp = (TzOrderCreateResp) result;

                if (resp == null || TextUtils.isEmpty(resp.getTxNo())) {
                    showOrderCreateErrorDialog("获取订单号失败，请重试");
                    return;
                }
                T.e(TAG, resp.toString());
                orderNo = resp.getTxNo();
                orderReqNo = orderNo + "0001";
                presenter.orderCreate(authCode, paymentAmountInt + "", orderNo, orderReqNo);
                break;
        }
    }

    private void showOrderCreateErrorDialog(String errorMsg) {
        dialog = new AlertDialog.Builder(getActivity()).create();
        dialog.setCancelable(false);
        dialog.setTitle(getString(R.string.dialog_title));
        dialog.setMessage(errorMsg + "，" + getString(R.string.please_retry));
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.text_ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                // 重新扫码
                restartPreviewAfterDelay(100);
            }
        });
        dialog.show();
    }

    @Override
    public void finishActivity() {
        Utils.safeDismissDialog(dotsDialog);
        Utils.safeDismissDialog(dialog);
        super.finishActivity();
    }

    @Override
    public Context getContext() {
        return getActivity();
    }


    /**
     * 返回键处理
     */
    public void onBackPressed() {
        finishActivity();
    }

    private void initDialog() {
        dotsDialog = new DilatingDotsDialog(getActivity(), getString(R.string.text_trading));
        dotsDialog.setCancelable(false);
        dotsDialog.setCanceledOnTouchOutside(false);
        dotsDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    showReverseDialog();
                }
                return false;
            }
        });
        dotsDialog.show();
    }

    private void showReverseDialog() {
        Utils.safeDismissDialog(dialog);
        dialog = new AlertDialog.Builder(getActivity()).create();
        dialog.setCancelable(false);
        dialog.setTitle(getString(R.string.cancel_order));
        dialog.setMessage(getString(R.string.message_reverse));
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.text_ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                showReverseProcessDialog();

            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.text_cancel), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    /**
     * 冲正
     */
    private void reverse() {
        isReverse = true;
        presenter.orderReverse(orderNo, orderReqNo, paymentAmountInt + "");
    }


    private void showReverseProcessDialog() {
//        Utils.safeDismissDialog(dotsDialog);
//        dotsDialog = new DilatingDotsDialog(getActivity(), getString(R.string.process));
//        dotsDialog.setCancelable(false);
//        dotsDialog.setCanceledOnTouchOutside(false);

        dotsDialog.setMessage(getString(R.string.process));
        dotsDialog.show();
        reverse();
    }

    /**
     * 订单支付失败
     *
     * @param message
     */
    private void showOrderErrorDialog(String message) {
        Utils.safeDismissDialog(dialog);
        Utils.safeDismissDialog(dotsDialog);
        dialog = new AlertDialog.Builder(getActivity()).create();
        dialog.setTitle(getString(R.string.dialog_title));
        dialog.setCancelable(false);
        dialog.setMessage(message);
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.text_ok), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                finishActivity();
            }
        });
        dialog.show();
    }

}
